#ifndef _RS485_APP_H_
#define _RS485_APP_H_

#include <stdint.h>
#include "485_protocol.h"

// #define INIT_TABLE {\
//     [CMD_OPEN_FOOR] = {\
//         .ParseFrameCallback = ParsingOpenSpecificFoorFrameCallback,\
//         .BuildResponseFrameCallback = BuildOpenSpecificFoorFrameCallback\
//     },\
// }

/**
 * @brief 报文解析结果
 *
 */
typedef enum
{
  RS485_EXECUTE_OVER,    // 完毕 Network
  RS485_EXECUTE_WAIT,    // 等待
  RS485_EXECUTE_ERROR,   // 错误
  RS485_EXECUTE_RETRY,   // 重试
  RS485_EXECUTE_SUCCESS, // 成功
} RS485ParsingResults_t;

/**
 * @brief 运行状态
 * 1：ota接收成功 2：ota接收失败 3：ota进行中 4：固件版本出错  5.运行中
 * 
 */
typedef enum{
    R_OTA_RECEIVE_SUCCESS = 1, // ota接收成功
    R_OTA_RECEIVE_FAILURE = 2, // ota接收失败
    R_OTA_RUNNING = 3,         // ota进行中
    R_FIRMWARE_VERSION_ERROR = 4, // 固件版本出错
    R_RUNNING = 5,             // 运行中
}IoBoadDeviceRunningStatus_t;


typedef enum{
  SEND_STEP_ONE,                      // 发送第1步
  SEND_STEP_TWO,                      // 发送第2步
  SEND_STEP_THREE,                    // 发送第3步
  SEND_STEP_FOUR,                     // 发送第4步
  RS485_ALL_COMMAND_EXECUTED,         // 所有命令已执行
}Rs485StepsOfSending_t;

/**
 * @brief 状态位
 *
 */
typedef struct
{
  Rs485StepsOfSending_t StepsOfSending;
} Rs485BitStatus_t;

/**
 * @brief  清除状态位
 * 
 * @return true 
 * @return false 
 */
extern bool ClearRs485BitStatus(void);

/**
 * @brief 打开指定楼层
 * 
 * @param parmIn 传入 ElectorData_t 结构体变量的地址
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildOpenSpecificFloorMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析打开指定楼层报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingOpenSpecificFloorMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief 构建获取版本号的报文
 * 
 * @param parmIn 传入一个非空的指针就行
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildGetVersionMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析获取版本号的报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingGetVersionMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief 构建开启紧急模式的报文
 * 
 * @param parmIn 传入一个非空的指针就行
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildOpenEmergencyModeMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析开启紧急模式的报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingOpenEmergencyModeMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief  构建固件传输的报文
 * 
 * @param parmIn 
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildIoBoardFirmwareTransMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief  解析固件传输的报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingIoBoardFirmwareTransMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief  构建查询固件状态的报文
 * 
 * @param parmIn 
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildQueryIoBoardFirmwareStatusMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief  构建查询固件状态的报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingQueryIoBoardFirmwareStatusMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief  构建查询io板mac地址的报文
 *
 * @param parmIn
 * @param pMessageOut
 * @param pSizeOut
 * @param pResponseTimeOut
 * @return true
 * @return false
 */
extern bool Rs485BuildQueryIoBoardMacAddressMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief  解析查询io板mac地址的报文
 * 
 * @param pDataIn
 * @param pDataSizeIn
 * @return uint8_t
 */
extern uint8_t Rs485ParsingQueryIoBoardMacAddressMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief  构建设置板自测试帧的报文
 * 
 * @param parmIn 
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildSetBoardSelfTestFrameMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief  构建设置板自测试帧的报文
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return uint8_t 
 */
extern uint8_t Rs485ParsingSetBoardSelfTestFrameMessage(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief 构建设置io板消防状态的报文 new
 * 
 * @param parmIn 
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildSetBoardFireAlarmWorkModeFrameMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析设置io板消防状态的报文 new
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return true 
 * @return false 
 */
extern uint8_t Rs485ParsingSetBoardFireAlarmWorkModeFrameCallback(const void *pDataIn, uint16_t pDataSizeIn);

/**
 * @brief 构建查询io板消防状态的报文 new
 * 
 * @param parmIn 
 * @param pMessageOut 
 * @param pSizeOut 
 * @param pResponseTimeOut 
 * @return true 
 * @return false 
 */
extern bool Rs485BuildQueryBoardFireAlarmStatusFrameMessage(void *parmIn, uint8_t *pMessageOut, uint16_t *pSizeOut, uint32_t *pResponseTimeOut);

/**
 * @brief 解析查询io板消防状态的报文 new
 * 
 * @param pDataIn 
 * @param pDataSizeIn 
 * @return true 
 * @return false 
 */
extern uint8_t Rs485ParsingQueryBoardFireAlarmStatusFrameCallback(const void *pDataIn, uint16_t pDataSizeIn);

#endif
